package com.qys.livesMall.navy.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Sets;
import com.qys.livesMall.anchor.business.LiveRoomGiftBusiness;
import com.qys.livesMall.anchor.constants.RedisConstant;
import com.qys.livesMall.anchor.mapper.AnchorLivesGiftMapper;
import com.qys.livesMall.anchor.model.dto.lives.app.ExchangeGoldDTO;
import com.qys.livesMall.anchor.model.dto.lives.app.GiveGiftDTO;
import com.qys.livesMall.anchor.model.entity.AnchorLivesGift;
import com.qys.livesMall.app.user.constants.TencentCloudImConstant;
import com.qys.livesMall.app.user.mapper.AppUserGoldAccountMapper;
import com.qys.livesMall.app.user.model.entity.AppUserGoldAccount;
import com.qys.livesMall.app.user.model.entity.H2AppUserBalance;
import com.qys.livesMall.app.user.service.IH2AppUserBalanceService;
import com.qys.livesMall.app.user.utils.TencentCloudIm;
import com.qys.livesMall.cache.RedisCache;
import com.qys.livesMall.common.exception.enums.ExceptionEnum;
import com.qys.livesMall.common.message.MessageServer;
import com.qys.livesMall.common.result.R;
import com.qys.livesMall.navy.common.Constant;
import com.qys.livesMall.navy.dao.NavyTaskDetailDao;
import com.qys.livesMall.navy.model.dto.task.AddLivesGift;
import com.qys.livesMall.navy.model.entity.NavyTask;
import com.qys.livesMall.navy.model.entity.NavyTaskDetail;
import com.qys.livesMall.navy.service.NavyLivesGiftService;
import com.qys.livesMall.navy.service.NavyTaskDetailService;
import com.qys.livesMall.navy.service.NavyTaskService;
import com.qys.livesMall.navy.task.TaskInter;
import com.qys.livesMall.shop.open.anchor.service.AnchorServer;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@Service
public class NavyLivesGiftServiceImpl implements NavyLivesGiftService {

    @Resource
    private MessageServer messageServer;

    @Resource
    private NavyTaskService navyTaskService;

    @Resource
    private NavyTaskDetailService navyTaskDetailService;

    @Resource
    private IH2AppUserBalanceService ih2AppUserBalanceService;

    @Resource
    private LiveRoomGiftBusiness liveRoomGiftBusiness;
    @Resource
    private AnchorLivesGiftMapper anchorLivesGiftMapper;
    @Resource
    private NavyTaskDetailDao navyTaskDetailDao;
    @Resource
    private RedisCache redisCache;
    @Resource
    private AnchorServer anchorServer;
    @Resource
    private TencentCloudIm tencentCloudIm;
    @Resource
    private AppUserGoldAccountMapper appUserGoldAccountMapper;

    @Resource
    @Lazy
    private TaskInter taskInter;

    @Override
    public R buildTask(AddLivesGift param) {
        if (param == null || CollectionUtils.isEmpty(param.getNavyIds()) || CollectionUtils.isEmpty(param.getLiveIds())
                || param.getAmount() == null) {
            return messageServer.failMsg(ExceptionEnum.PARAM_IS_ERROR);
        }
        NavyTask navyTask = new NavyTask();
        navyTask.setTaskType(Constant.TaskType.LIVES_GIFT);
        navyTask.setTaskName("直播礼物");
        navyTask.setTaskParam(JSONObject.toJSONString(param));
        navyTask.setTaskStatus(Constant.TaskStatus.RUNNING);
        navyTask.setTaskStartTime(LocalDateTime.now());
        navyTask.setCreateDate(LocalDateTime.now());
        navyTask.setUpdDate(LocalDateTime.now());
        navyTaskService.save(navyTask);
        //创建任务明细
        NavyTaskDetail detail = new NavyTaskDetail();
        detail.setTaskId(navyTask.getId());
        detail.setTaskType(navyTask.getTaskType());
        detail.setSort(1);
        detail.setAmount(param.getAmount());
        detail.setNavyIds(String.join(",", param.getNavyIds()));
        detail.setLivesIds(String.join(",", param.getLiveIds()));
        detail.setCreateDate(LocalDateTime.now());
        detail.setTaskStatus(Constant.TaskDetailStatus.NO_START);
        navyTaskDetailDao.save(detail);
        taskInter.addLivesGiftTask(1, detail.getId());
        return R.ok();
    }

    @Override
    @Async
    public void exc(Long taskDetailId) {
        log.info("水军批量礼物执行开始，{}", taskDetailId);
        NavyTaskDetail detail = navyTaskDetailService.getById(taskDetailId);
        if (detail == null) {
            return;
        }
        String[] userIds = detail.getNavyIds().split(",");
        String[] livesIds = detail.getLivesIds().split(",");

        //查询礼物
        LambdaQueryWrapper<AnchorLivesGift> giftQeury = Wrappers.lambdaQuery(AnchorLivesGift.class)
                .eq(AnchorLivesGift::getStatus, 0)
                .eq(AnchorLivesGift::getDeleted, 0);
        List<AnchorLivesGift> anchorLivesGifts = anchorLivesGiftMapper.selectList(giftQeury);

        //可用总金额
        BigDecimal totalAmountAvailable = detail.getAmount();
        //已用金额
        BigDecimal amountSpent = BigDecimal.ZERO;
        try {
            for (String livesId : livesIds) {
                //获取直播间编号
                String roomNumber = anchorServer.getRoomInfoByLivesSessionId(Long.valueOf(livesId));
                for (String navyId : userIds) {
                    //获取水军金币余额
                    AppUserGoldAccount account = appUserGoldAccountMapper.selectOne(Wrappers.<AppUserGoldAccount>lambdaQuery().eq(AppUserGoldAccount::getUserId, navyId));
                    //匹配礼物
                    List<AnchorLivesGift> giftList = anchorLivesGifts.stream().filter(m -> m.getGiftGold().doubleValue() <= (account.getGoldAmount().doubleValue())).toList();
                    if(CollectionUtils.isEmpty(giftList)){
                        //获取当前水军账户
                        H2AppUserBalance h2AppUserBalance = ih2AppUserBalanceService.queryByUserId(Long.valueOf(navyId));
                        if (null == h2AppUserBalance || null == h2AppUserBalance.getBalance() || h2AppUserBalance.getBalance().equals(BigDecimal.ZERO)) {
                            log.info("水军直播礼物:未获取到水军账户或余额不足:{}", navyId);
                            continue;
                        }
                        //兑换金币
                        ExchangeGoldDTO exchangeGoldDTO = new ExchangeGoldDTO();
                        exchangeGoldDTO.setExchangeGoldQuantity(h2AppUserBalance.getBalance().divide(BigDecimal.TEN, 2, RoundingMode.DOWN).multiply(BigDecimal.valueOf(100L)));
                        exchangeGoldDTO.setUserId(Long.valueOf(navyId));
                        liveRoomGiftBusiness.exchangeGold(exchangeGoldDTO);
                        //获取水军金币余额
                        AppUserGoldAccount newAccount = appUserGoldAccountMapper.selectOne(Wrappers.<AppUserGoldAccount>lambdaQuery().eq(AppUserGoldAccount::getUserId, navyId));
                        //匹配礼物
                        giftList = anchorLivesGifts.stream().filter(m -> m.getGiftGold().doubleValue() <= (newAccount.getGoldAmount().doubleValue())).toList();
                    }

                    if(CollectionUtils.isEmpty(giftList)){
                        log.info("水军直播礼物:金币无法购买礼物:{}", navyId);
                        continue;
                    }
                    AnchorLivesGift gift = giftList.get(RandomUtil.randomInt(giftList.size()));
                    amountSpent = amountSpent.add(gift.getGiftGold().divide(BigDecimal.valueOf(100L),2, RoundingMode.DOWN));
                    if(totalAmountAvailable.compareTo(amountSpent) < 0){
                        log.info("水军直播礼物:已达到最高金额:{}", navyId);
                        continue;
                    }

                    //计入观看人数
                    String key = RedisConstant.LIVE_ONLINE_NUMBER_PREFIX + livesId;
                    Long size = redisCache.size(key);
                    Set<String> cacheSet;
                    if(size == 0){
                        cacheSet = Sets.newHashSet("navy" + navyId);
                        //伪装进入直播间
                        tencentCloudIm.sendGroupMsg(navyId, anchorServer.getRoomInfoByLivesSessionId(Long.valueOf(livesId)), TencentCloudImConstant.TIM_CUSTOM_ELEM, "enter");
                    } else {
                        cacheSet = redisCache.getCacheSet(key);
                        if(!redisCache.getCacheSet(key).contains("navy" + navyId)){
                            //伪装进入直播间
                            tencentCloudIm.sendGroupMsg(navyId, anchorServer.getRoomInfoByLivesSessionId(Long.valueOf(livesId)), TencentCloudImConstant.TIM_CUSTOM_ELEM, "enter");
                            cacheSet.add("navy" + navyId);
                        }
                    }
                    redisCache.setCacheSet(key, cacheSet);

                    try {
                        Thread.sleep(RandomUtil.randomLong(5000, 10000));
                    } catch (Exception ignored) {

                    }

                    String content = gift.getGiftIcon() + ",1," + "https://lives-mall.51dsha.com/" + gift.getGiftStyle();
                    tencentCloudIm.sendGroupMsg(navyId, anchorServer.getRoomInfoByLivesSessionId(Long.valueOf(livesId)), TencentCloudImConstant.TIM_CUSTOM_ELEM, content);

                    //调用送礼接口
                    GiveGiftDTO giveGiftDTO = new GiveGiftDTO();
                    giveGiftDTO.setId(gift.getId());
                    giveGiftDTO.setQuantity(1);
                    giveGiftDTO.setLivesRoomNum(roomNumber);
                    giveGiftDTO.setLivesSessionId(Long.valueOf(livesId));
                    liveRoomGiftBusiness.giveGift(giveGiftDTO, Long.valueOf(navyId));
                }
            }
        } catch (Exception e) {
            detail.setTaskStatus(Constant.TaskDetailStatus.END_FAIL);
            detail.setTaskDate(LocalDateTime.now());
            navyTaskDetailService.upById(detail);
            log.info("水军批量礼物执行失败:{}", taskDetailId);
            log.error("水军批量礼物执行异常", e);
            return;
        }

        detail.setTaskStatus(Constant.TaskDetailStatus.END_SUCCESS);
        navyTaskDetailService.upById(detail);
        //同步主任务状态
        navyTaskService.watchTaskEnd(detail.getTaskId());
    }
}
